package org.voovan.korla.socket;

import org.voovan.network.IoSession;

import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * session 缓存池
 *
 * @author: helyho
 * korla Framework.
 * WebSite: https://github.com/helyho/korla
 * Licence: Apache v2 License
 */
public class SessionCache {
    private String channel;

    private Vector<IoSession> sessions = new Vector<IoSession>();

    private AtomicInteger loopIndex = new AtomicInteger();

    public SessionCache(String channel) {
        this.channel = channel;
    }

    public String getChannel() {
        return channel;
    }

    public void setChannel(String channel) {
        this.channel = channel;
    }

    public int getLoopIndex() {
        return loopIndex.get();
    }

    public Vector<IoSession> getSessions() {
        return sessions;
    }

    public void put(IoSession session) {
        sessions.add(session);
    }

    public boolean contain(IoSession session) {
        return sessions.contains(session);
    }

    public boolean remove(IoSession session) {
        return sessions.remove(session);
    }

    public IoSession getLoopNext() {
        while(sessions.size() > 0) {

            int nextIndex = loopIndex.getAndUpdate(currentVal -> {
                if(currentVal + 1 >= sessions.size()) {
                   return 0;
                }
                return currentVal + 1;
            });

            IoSession session = sessions.get(nextIndex);
            if(session!=null) {
                if(session.isConnected()) {
                    return session;
                } else {
                    sessions.remove(session);
                }
            }
        }

        return null;
    }

    public IoSession getRandom() {
        while(sessions.size() > 0) {
            int randomIndex = (int) ((sessions.size()-1)*Math.random());
            IoSession ioSession = sessions.get(randomIndex);

            if(ioSession!=null) {
                if(ioSession.isConnected()) {
                    return ioSession;
                } else {
                    sessions.remove(ioSession);
                }
            }
        }

        return null;
    }
}
